using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;

using Deepcode.Flux.Core.Services.FluxClient;
using Deepcode.Flux.Core.Systems.CMS;
using Deepcode.Flux.Core.Systems.CMS.DataTaxonomy;

namespace Deepcode.Flux.Core.UI.Controls
{
	/// <summary>
	/// DataTaxonomySelection is a special tree view implementation that
	/// allows for the rendering of the data taxonomy tree with checkboxes
	/// associated with them.
	/// </summary>
	public class DataTaxonomySelection : System.Web.UI.WebControls.TreeView
	{
		#region Properties
		/// <summary>
		/// Specifies the root of the taxonomy node by string. This allows you 
		/// to load taxonomy by specifying the path eg: /My node/XYZ/Blah/
		/// as being the root node. This in turn looks up the node path
		/// and sets the RootTaxonomyNodeID property. If this fails to find the
		/// node, it will use the root taxonomy node.
		/// </summary>
		public string RootTaxonomyNode
		{
			set
			{
				DataTaxonomyTree tree = new DataTaxonomyTree();
				DataTaxonomyNode node = tree.GetPath( value );
				if (node == null) 
					RootTaxonomyNodeID = -1;
				else
					RootTaxonomyNodeID = node.PK_ID;
			}
		}
		/// <summary>
		/// Specifies the ID of the root taxonomy node.
		/// </summary>
		public int RootTaxonomyNodeID
		{
			get
			{
				object vs = ViewState["rootid"];
				if( vs == null ) return -1;
				return (int) vs;
			}
			set
			{
				ViewState["rootid"] = value;
			}
		}
		#endregion
		#region Flux client helpers
		/// <summary>
		/// Loads a stylesheet from the flux_client mapping
		/// </summary>
		/// <param name="ClientCSS"></param>
		/// <param name="UniqueID"></param>
		protected void LoadClientStyleSheet(string ClientCSS, string UniqueID)
		{
			Page.ClientScript.RegisterClientScriptBlock(this.GetType(), UniqueID, 
				String.Format("<link rel=\"stylesheet\" href=\"{0}\"/>",
					ClientHelper.GetFluxClientFile(ClientCSS)));
		}
		#endregion
		#region Initialisation
		/// <summary>
		/// Initialise treeview defaults
		/// </summary>
		/// <param name="e"></param>
		protected override void OnInit(EventArgs e)
		{
			base.OnInit(e);
			this.LoadClientStyleSheet("DataTaxonomySelection/DTStyle.css", "Deepcode.Flux.Core.UI.Controls.DataTaxonomySelection");		
			this.ShowCheckBoxes = TreeNodeTypes.All;
			this.ShowExpandCollapse = true;
			this.ShowLines = true;
			this.NodeStyle.CssClass = "TREE_nodestyle";
			this.SelectedNodeStyle.CssClass = "TREE_nodestyleselected";
		}
		/// <summary>
		/// On load event
		/// </summary>
		/// <param name="e"></param>
		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);
			if( ! Page.IsPostBack ) PopulateTaxonomy( null );
		}
		#endregion
		#region Population and loading
		/// <summary>
		/// Flag indicating if the taxonomy has been populated or not
		/// </summary>
		protected bool Populated = false;
		/// <summary>
		/// Populate the taxonomy tree and load flags from the object passed in
		/// </summary>
		public void PopulateTaxonomy( ContentObject load )
		{
			if (!Page.IsPostBack && !Populated)
			{
				Populated = true;
				Populate(this.Nodes, RootTaxonomyNodeID, load);
			}
		}
		/// <summary>
		/// Populates the data taxonomy tree nodes
		/// </summary>
		/// <param name="destination"></param>
		/// <param name="parentid"></param>
 		protected void Populate(TreeNodeCollection destination, int parentid, ContentObject load)
		{
			DataTaxonomyTree t = new DataTaxonomyTree();
			DataTaxonomyNode [] nodes = t.GetForParentID( parentid );

			foreach (DataTaxonomyNode n in nodes)
			{
				TreeNode node = new TreeNode();
				node.Text = n.Name;
				node.Value = n.PK_ID.ToString();
				node.SelectAction = TreeNodeSelectAction.None;
				node.ImageUrl = ClientHelper.GetFluxClientFile("DataTaxonomySelection/icon.gif");

				if ((load != null) && (load.DataTaxonomyCategories.Contains(n.PK_ID)))
				{
					node.Checked = true;
					TreeNode trav = node.Parent;
					while (trav != null)
					{
						trav.Expanded = true;
						trav = trav.Parent;
					}
				}
				else
				{
					node.Checked = false;
					if (parentid == RootTaxonomyNodeID) node.Expanded = true;
					else node.Expanded = false;
				}

				destination.Add( node );
				Populate( node.ChildNodes, n.PK_ID, load );
			}
		}
		#endregion
		#region Saving
		/// <summary>
		/// Takes the data taxonomy selections on the tree view control
		/// and stores them in the content object referenced.
		/// </summary>
		/// <param name="Save"></param>
		public void QuickSave(ref ContentObject Save)
		{
			// Clear the save object's data taxonomy
			Save.DataTaxonomyCategories.Clear();

			// Get the root object and ensure it and its parents are added in if we have anything selected
			if ((this.RootTaxonomyNodeID != -1) && ( this.CheckedNodes.Count > 0))
			{
				DataTaxonomyTree tree = new DataTaxonomyTree();
				DataTaxonomyNode root = tree.GetByID( this.RootTaxonomyNodeID );
				while (root != null)
				{
					Save.DataTaxonomyCategories.Add( root.PK_ID );
					root = root.Parent;
				}
			}

			// Now store each one in the save object
			foreach (TreeNode node in this.CheckedNodes)
			{
				Save.DataTaxonomyCategories.Add(Int32.Parse(node.Value));
				// Ensure each parent key is also added
				TreeNode trav = node.Parent;
				while (trav != null)
				{
					Save.DataTaxonomyCategories.Add( Int32.Parse( trav.Value ));
					trav = trav.Parent;
				}
			}
		}
		#endregion
	}
}
